package com.sugree.thairath.breakingnews;

import java.util.List;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.SharedPreferences;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.Log;

import com.sugree.base.BreakingNewsUpdateService;
import com.sugree.util.entity.Message;

public class BreakingNewsService extends Service {
	private static final String TAG = "BreakingNewsWidget";

	protected AlarmManager mAlarmManager;
	protected PowerManager mPM;
	protected PowerManager.WakeLock mWL;
	protected SharedPreferences mSP;
	protected BreakingNewsUpdateService mService;
	protected final RemoteCallbackList<IBreakingNewsServiceCallback> mCallbacks = new RemoteCallbackList<IBreakingNewsServiceCallback>();

	@Override
	public void onCreate() {
		mService = new BreakingNewsUpdateService(this,
				mHandler,
				BreakingNewsWidget.class,
				BreakingNewsList.class,
				BreakingNewsItem.class,
				C.config.feed_url,
				C.config.encoding,
				R.string.template_user_agent,
				R.string.notification_format,
				R.string.notification_singular,
				R.string.notification_plural,
				R.drawable.notification,
				R.string.notification_title,
				R.layout.widget_news,
				R.id.title,
				R.id.logo);
		PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
		mAlarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
		mPM = (PowerManager)getSystemService(POWER_SERVICE);
		mWL = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
	}

	@Override
	public void onStart(Intent intent, int startId) {
		Log.d(TAG, "start");

		Log.d(TAG, "acquire");
		mWL.acquire();

		mSP = PreferenceManager.getDefaultSharedPreferences(this);
		long interval = Long.parseLong(mSP.getString(BreakingNewsPreference.REFRESH_INTERVAL, "0"));
		boolean notify = mSP.getBoolean(BreakingNewsPreference.NOTIFICATION_ENABLED, true);
		boolean vibration = mSP.getBoolean(BreakingNewsPreference.VIBRATION, true);
		String ringtone = mSP.getString(BreakingNewsPreference.RINGTONE, null);

		mService.onStart(intent, startId, notify, vibration, ringtone);

		if (interval > 0) {
			Intent i = new Intent(this, BreakingNewsReceiver.class);
			i.setAction(Intent.ACTION_MAIN);
			PendingIntent pending = PendingIntent.getBroadcast(this, 0, i, 0);

			long triggerTime = SystemClock.elapsedRealtime()+interval*1000;
			mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, pending);
			Log.d(TAG, "time "+SystemClock.elapsedRealtime());
			Log.d(TAG, "set alarm "+triggerTime+" "+interval);
		}
	}

	@Override
	public void onDestroy() {
		mCallbacks.kill();
		mService.onStop();
		while (mWL.isHeld()) {
			Log.d(TAG, "release");
			mWL.release();
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	public void fireChange(boolean changed) {
		final int N = mCallbacks.beginBroadcast();
		for (int i=0; i<N; i++) {
			Log.d(TAG, "fireChange "+i);
			try {
				mCallbacks.getBroadcastItem(i).valueChanged(changed);
			} catch (RemoteException e) {
			}
		}
		mCallbacks.finishBroadcast();
		Log.d(TAG, "release");
		mWL.release();
	}

	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(android.os.Message msg) {
			Log.d(TAG, "handleMessage "+msg.what);
			switch (msg.what) {
				case BreakingNewsUpdateService.MSG_CHANGED:
					fireChange(true);
					break;
				case BreakingNewsUpdateService.MSG_NOT_CHANGED:
					fireChange(false);
					break;
				default:
					super.handleMessage(msg);
			}
		}
	};

	private final IBreakingNewsService.Stub mBinder = new IBreakingNewsService.Stub() {
		public List<Message> getItems() {
			return mService.getItems();
		}

		public void registerCallback(IBreakingNewsServiceCallback cb) {
			if (cb != null) {
				mCallbacks.register(cb);
			}
		}

		public void unregisterCallback(IBreakingNewsServiceCallback cb) {
			if (cb != null) {
				mCallbacks.unregister(cb);
			}
		}
	};
}
